#include "BlocksCan.h"
#include "CanObserver.h"


BlocksCan::BlocksCan(CanObserver* canObserver, unsigned char width, unsigned char height) 
: _width(width)
, _height(height)
, _cellSize(25) 
, _observer(canObserver)
{
    Clear();
}

void BlocksCan::CheckLines(unsigned lower, unsigned upper)
{
	if (upper < RedLine())
	{
		unsigned linesRemoved = 0;
		unsigned lineIndex	  = upper;

		do
		{
			unsigned cellIndex = 0;
			while ((cellIndex < _width) && _cells[cellIndex + lineIndex*_width]) ++cellIndex;

			if (cellIndex == _width)
			{
				_RemoveLine(lineIndex);
				++linesRemoved;
			}
		}
		while (lineIndex-- > lower);

		if (linesRemoved)
			_observer->ReportLinesRemoval(linesRemoved);
	}
	else
	{
		_observer->ReportLoseState();
	}
}

void BlocksCan::_RemoveLine(unsigned line)
{	
	Cells::iterator startIterator = _cells.begin();
	Cells::iterator destIterator  = _cells.begin();

	std::advance(startIterator, (line+1)*_width);
	std::advance(destIterator , line*_width    );

	std::copy(startIterator, _cells.end(), destIterator);
}

void BlocksCan::Clear()
{
	_cells.clear();
	_cells.resize(_width*_height, CELL_FREE);
}

unsigned char BlocksCan::Width()
{
    return _width;
}

unsigned char BlocksCan::RedLine()
{
    return HEIGHT;  
}

unsigned char BlocksCan::Height()
{
    return _height;
}

unsigned char BlocksCan::CellSize()
{
    return _cellSize;
}

unsigned char BlocksCan::ReadCell(unsigned x, unsigned y)
{
    return (x >= _width || y >= _height) ? CELL_OCCUPIED : _cells[x + y*_width];
}

unsigned char& BlocksCan::Cell(unsigned x, unsigned y)	
{
    return _cells[x + y*_width];
}
